package com.raymond.http;


import com.raymond.http.config.HttpConfig;
import com.raymond.http.netty.DefaultHttpClientHandler;
import com.raymond.http.netty.HttpAddress;
import com.raymond.http.netty.HttpFixedChannelPool;
import com.raymond.http.netty.HttpNetty;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.pool.FixedChannelPool;
import io.netty.channel.pool.SimpleChannelPool;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * http的netty客户端
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2021-12-11 18:12
 */
@Slf4j
public class HttpNettyClient {


    private HttpNetty httpNetty;

    public HttpNettyClient() {
        this(new HttpNetty());
    }

    public HttpNettyClient(HttpConfig config) {
        this(new HttpNetty(config));
    }

    public HttpNettyClient(HttpNetty httpNetty) {
        this.httpNetty = httpNetty;
        httpNetty.init();

    }

    public MessageManages execute(String url) {
        HttpRequest httpRequest = HttpClientUtil.getHttpRequest(url);
        return execute(httpRequest);
    }

    int count = 0;

    int totalTime = 0;

    int time = 0;

    int totalCount = 0;

    public MessageManages execute(HttpRequest httpRequest) {
        return execute(httpRequest, null);
    }


    public MessageManages execute(HttpRequest httpRequest, HttpAddress proxy) {

        String uri = httpRequest.uri();
        HttpFixedChannelPool fixedChannelPool = proxy == null ? httpNetty.getFixedChannelPool(uri) : httpNetty.getFixedChannelPool(proxy);
//        int i = fixedChannelPool.availablePermits();
//        if (i > 3) {
//            log.debug("通道数量：{}", fixedChannelPool.availablePermits());
//        }
        totalCount++;

        long start = System.currentTimeMillis();
        Channel channel = httpNetty.getChannel(fixedChannelPool);
        long end = System.currentTimeMillis() - start;
        totalTime += end;
        if (end > 5) {
            count ++;
            time += end;
            log.debug("获取通道耗时过长,总次数：{},次数：{}, 总耗时：{}, 超时耗时:{}, 当前耗时:{}, channel:{}", totalCount, count, totalTime, time, end, channel);
        }
        MessageManages messageManages = new MessageManages(new DefaultPromise<>(GlobalEventExecutor.INSTANCE), uri);
        ((DefaultHttpClientHandler) channel.pipeline().get("httpClientHandler")).setMessageManages(messageManages);
        ChannelFuture channelFuture = httpNetty.request(channel, httpRequest);
        channelFuture.addListener((ChannelFutureListener) future1 -> {
            if (future1.isSuccess()) {
//                log.debug("通道id={}刷出数据成功!", future1.channel().id());
            } else {
                log.error("通道id={}刷出数据失败!", future1.channel().id());
                fixedChannelPool.release(channel);
            }
        });
        return null;
    }

}
